package com.guli.product.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guli.common.to.SkuFullReductionTo;
import com.guli.common.to.SkuLadderTo;
import com.guli.common.to.SpuBoundTo;
import com.guli.common.to.esmodel.AttrModel;
import com.guli.common.to.esmodel.SkuEsModel;
import com.guli.common.utils.PageUtils;
import com.guli.common.utils.Query;
import com.guli.common.utils.R;
import com.guli.product.dao.*;
import com.guli.product.entity.*;
import com.guli.product.feign.CouponFeign;
import com.guli.product.feign.SearchFeign;
import com.guli.product.feign.WareFeign;
import com.guli.product.service.*;
import com.guli.product.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import com.guli.product.entity.SpuInfoEntity;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    private SpuInfoDao spuInfoDao;
    @Autowired
    private SpuInfoDescDao spuInfoDescDao;
    @Autowired
    private SpuImagesService spuImagesService;
    @Autowired
    private AttrDao attrDao;
    @Autowired
    private ProductAttrValueService productAttrValueService;
    @Autowired
    private SkuInfoService skuInfoService;
    @Autowired
    private SkuImagesDao skuImagesDao;
    @Autowired
    private CouponFeign couponFeign;
    @Autowired
    private SkuSaleAttrValueDao skuSaleAttrValueDao;
    @Autowired
    private BrandDao brandDao;
    @Autowired
    private CategoryDao categoryDao;
    @Autowired
    private WareFeign wareFeign;
    @Autowired
    private ProductAttrValueDao productAttrValueDao;
    @Autowired
    private AttrService attrService;
    @Autowired
    private SearchFeign searchFeign;
    @Autowired
    private ThreadPoolExecutor executor;
    @Autowired
    private SkuCanalService skuCanalService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String status = (String) params.get("status");
        String key = (String) params.get("key");
        String brandId = (String) params.get("brandId");
        String categoryId = (String) params.get("categoryId");
        QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(status)) {
            wrapper.eq("publish_status", status);
        }
        if (!StringUtils.isEmpty(key)) {
            wrapper.like("spu_name", key).or().eq("id", key);
        }
        if (!StringUtils.isEmpty(brandId)) {
            if (!"0".equals(brandId)) {
                wrapper.eq("brand_id", brandId);
            }
        }
        if (!StringUtils.isEmpty(categoryId)) {
            if (!"0".equals(categoryId)) {
                wrapper.eq("category_id", categoryId);
            }
        }
        IPage<SpuInfoEntity> pages = spuInfoDao.selectPage(new Query<SpuInfoEntity>().getPage(params), wrapper);
        List<SpuInfoEntity> spuInfos = pages.getRecords();
        if (!CollectionUtils.isEmpty(spuInfos)) {
            spuInfos.forEach(spu -> {
                Long id = spu.getCategoryId();
                CategoryEntity category = categoryDao.selectById(id);
                if (category != null) {
                    spu.setCategoryName(category.getName());
                }
                Long brandId1 = spu.getBrandId();
                BrandEntity brand = brandDao.selectById(brandId1);
                if (brand != null) {
                    spu.setBrandName(brand.getName());
                }
            });
        }
        pages.setRecords(spuInfos);
        return new PageUtils(pages);
    }

    //TODO 待优化

    /**
     * 保存商品信息
     * @param spuSaveVo
     */
    @Override
    public void saveSpuInfoAndSkuAndOther(SpuSaveVo spuSaveVo) {
        //保存进pms_spu_info表  spu基本信息
        SpuInfoEntity spuInfo = new SpuInfoEntity();
        BeanUtils.copyProperties(spuSaveVo, spuInfo);
        spuInfo.setCreateTime(new Date());
        spuInfo.setUpdateTime(new Date());
        spuInfoDao.insert(spuInfo);
        CompletableFuture.runAsync(() -> {
            //保存进pms_spu_info_desc表    spu的描述图片
            SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
            spuInfoDescEntity.setSpuId(spuInfo.getId());
            List<String> decript = spuSaveVo.getDecript();
            spuInfoDescEntity.setDecript(String.join(",", decript));
            spuInfoDescDao.insert(spuInfoDescEntity);
        }, executor);
        CompletableFuture.runAsync(() -> {
            //保存进pms_spu_images表    spu图片集
            if (!CollectionUtils.isEmpty(spuSaveVo.getImages())) {
                List<SpuImagesEntity> SpuImagesList = spuSaveVo.getImages().stream().map(spuSaveImage -> {
                    if (StringUtils.isEmpty(spuSaveImage)) {
                        return null;
                    }
                    SpuImagesEntity spuImages = new SpuImagesEntity();
                    spuImages.setSpuId(spuInfo.getId());
                    spuImages.setImgUrl(spuSaveImage);
                    return spuImages;
                }).collect(Collectors.toList());
                spuImagesService.saveBatch(SpuImagesList);
            }
        }, executor);
        CompletableFuture.runAsync(() -> {
            //保存进pms_product_attr_value表    spu规格参数
            if (!CollectionUtils.isEmpty(spuSaveVo.getBaseAttrs())) {
                List<ProductAttrValueEntity> productAttrValueList = spuSaveVo.getBaseAttrs().stream().map(baseAttr -> {
                    ProductAttrValueEntity productAttrValue = new ProductAttrValueEntity();
                    productAttrValue.setSpuId(spuInfo.getId());
                    productAttrValue.setAttrId(baseAttr.getAttrId());
                    productAttrValue.setAttrValue(baseAttr.getAttrValues());
                    AttrEntity attr = attrDao
                            .selectOne(new QueryWrapper<AttrEntity>().eq("attr_id", baseAttr.getAttrId()));
                    productAttrValue.setAttrName(attr.getAttrName());
                    return productAttrValue;
                }).collect(Collectors.toList());
                productAttrValueService.saveBatch(productAttrValueList);
            }
        }, executor);
        CompletableFuture.runAsync(() -> {
            //保存spu的积分信息  sms_spu_bounds
            Bounds bounds = spuSaveVo.getBounds();
            SpuBoundTo spuBoundTo = new SpuBoundTo();
            spuBoundTo.setSpuId(spuInfo.getId());
            spuBoundTo.setBuyBounds(bounds.getBuyBounds());
            spuBoundTo.setGrowBounds(bounds.getGrowBounds());
            couponFeign.saveSpuBoundTo(spuBoundTo);
        }, executor);
        CompletableFuture.runAsync(() -> {
            //保存pms_sku_info表 当前spu对应的所有sku信息
            List<Skus> skus = spuSaveVo.getSkus();
            if (!CollectionUtils.isEmpty(skus)) {
                skus.forEach(sku -> {
                    //sku基本信息  pms_sku_info
                    SkuInfoEntity skuInfo = new SkuInfoEntity();
                    BeanUtils.copyProperties(sku, skuInfo);
                    skuInfo.setSpuId(spuInfo.getId());
                    skuInfo.setCategoryId(spuSaveVo.getCategoryId());
                    skuInfo.setBrandId(spuSaveVo.getBrandId());
                    skuInfo.setSaleCount(0L);
                    List<Images> images = sku.getImages();
                    String defaultImage = "";
                    for (Images image : images) {
                        if (image.getDefaultImg() == 1) {
                            defaultImage = image.getImgUrl();
                            break;
                        }
                    }
                    skuInfo.setSkuDefaultImg(defaultImage);
                    skuInfoService.save(skuInfo);
                    //sku图片信息  pms_sku_images
                    Long skuId = skuInfo.getSkuId();
                    if (!CollectionUtils.isEmpty(images)) {
                        images.forEach(image -> {
                            if (StringUtils.isEmpty(image.getImgUrl())) {
                                return;
                            }
                            SkuImagesEntity skuImage = new SkuImagesEntity();
                            skuImage.setSkuId(skuId);
                            if (image.getDefaultImg() == 1) {
                                skuImage.setDefaultImg(1);
                            } else {
                                skuImage.setDefaultImg(0);
                            }
                            skuImage.setImgUrl(image.getImgUrl());
                            //TODO 待测试
                            skuImagesDao.insert(skuImage);
                        });
                        //sku销售属性信息 pms_sku_sale_attr_value
                        List<Attr> attrs = sku.getAttr();
                        attrs.forEach(attr -> {
                            SkuSaleAttrValueEntity skuSaleAttrValue = new SkuSaleAttrValueEntity();
                            BeanUtils.copyProperties(attr, skuSaleAttrValue);
                            skuSaleAttrValue.setSkuId(skuId);
                            skuSaleAttrValueDao.insert(skuSaleAttrValue);
                        });
                    }
                    //保存满减信息 sms_sku_full_reduction
                    //TODO
                    SkuFullReductionTo skuFullReductionTo = new SkuFullReductionTo();
                    BeanUtils.copyProperties(sku, skuFullReductionTo);
                    skuFullReductionTo.setSkuId(skuId);
                    couponFeign.saveSkuFullReductionTo(skuFullReductionTo);
                    //保存折扣信息 sms_sku_ladder
                    //TODO
                    SkuLadderTo skuLadderTo = new SkuLadderTo();
                    BeanUtils.copyProperties(sku, skuLadderTo);
                    skuLadderTo.setSkuId(skuId);
                    couponFeign.saveSkuLadderTo(skuLadderTo);
                });
            }
        }, executor);
    }

    /*
     * 需要重新封装
     * private List<Attr> attrs;
     * */
    @Override
    public void spuUp(Long spuId) {
        //根据spuId查询所有sku信息
        List<SkuInfoEntity> skuInfoEntityList =
                skuInfoService.list(new QueryWrapper<SkuInfoEntity>().eq("spu_id", spuId));
        //根据spuId查询所有基本规格参数
        List<ProductAttrValueEntity> productAttrs = productAttrValueDao
                .selectList(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));
        List<AttrModel> attrs;
        if (!CollectionUtils.isEmpty(productAttrs)) {
            List<Long> attrIds = productAttrs.stream()
                    .map(ProductAttrValueEntity::getAttrId).collect(Collectors.toList());
            List<AttrEntity> attrEntityList = attrService.listByIds(attrIds).stream()
                    .filter(attrEntity -> attrEntity.getSearchType() == 1).collect(Collectors.toList());
            //查询所有可检索的属性
            List<Long> attrIdsWithSearch = attrEntityList.stream().map(AttrEntity::getAttrId).collect(Collectors.toList());
            attrs = productAttrs.stream().filter(item -> attrIdsWithSearch.contains(item.getAttrId())).map(productAttr -> {
                AttrModel attr = new AttrModel();
                BeanUtils.copyProperties(productAttr, attr);
                return attr;
            }).collect(Collectors.toList());
        } else {
            attrs = null;
        }
        //封装SkuEsModel
        List<SkuEsModel> skuEsModels = skuInfoEntityList.stream().map(sku -> {
            SkuEsModel skuEsModel = new SkuEsModel();
            BeanUtils.copyProperties(sku, skuEsModel);
            /*skuEsModel.setId(IdUtil.getSnowflakeNextId());*/
            //设置SkuPrice
            skuEsModel.setSkuPrice(sku.getPrice());
            //设置skuImg
            skuEsModel.setSkuImg(sku.getSkuDefaultImg());
            //设置brandName
            //根据brandId查询brandName
            BrandEntity brand = brandDao.selectById(sku.getBrandId());
            skuEsModel.setBrandName(brand.getName());
            //设置brandImg
            skuEsModel.setBrandImg(brand.getLogo());
            //设置categoryName
            CategoryEntity category = categoryDao.selectById(sku.getCategoryId());
            skuEsModel.setCategoryName(category.getName());
            skuEsModel.setCategoryId(category.getCatId());
            //设置热度评分
            skuEsModel.setHotScore(0L);
            //查询库存是否充足
            R hasStock = wareFeign.hasStock(sku.getSkuId());
            Boolean stock = hasStock.getData(new TypeReference<Boolean>() {
            });
            skuEsModel.setHasStock(stock);
            //设置attrs
            skuEsModel.setAttrs(attrs);
            return skuEsModel;
        }).collect(Collectors.toList());
        // 将skuEsModels同步到pms_sku_canal表中
        List<SkuCanal> skuCanals = skuEsModels.stream().map(skuEsModel -> {
            SkuCanal skuCanal = new SkuCanal();
            BeanUtils.copyProperties(skuEsModel, skuCanal);
            List<AttrModel> attrModels = skuEsModel.getAttrs();
            //将attrModels转化为JSON
            String attrJson = JSON.toJSONString(attrModels);
            skuCanal.setAttrs(attrJson);
            return skuCanal;
        }).collect(Collectors.toList());
        //TODO 减去锁定库存问题 商品上架失败，幂等性问题，重试机制
        skuCanalService.saveBatch(skuCanals);
        R ifUp = searchFeign.productUp(skuEsModels);
        if ((Integer) ifUp.get("code") == 0) {
            log.debug("商品上架成功");
            //改变spu的发布状态
            spuInfoDao.updateStatus(spuId);
        } else {
            log.debug("商品上架出错");

        }
    }
}